package ink.tiptop.service.impl;

import com.trilead.ssh2.Connection;
//import ink.tiptop.bean.cache.RestartServiceBean;
import ink.tiptop.dto.req.RestartServiceBean;
import ink.tiptop.persist.domain.entity.ZjfBaseServerInfoEntity;
import ink.tiptop.persist.domain.entity.ZjfServiceRemoteViewEntity;
import ink.tiptop.dto.req.remote.restart.RestartServiceListRequest;
import ink.tiptop.dto.req.remote.restart.RestartServiceRequest;
import ink.tiptop.common.domain.WebworkResponse;
import ink.tiptop.common.cache.ECaches;
import ink.tiptop.common.cache.ICache;
import ink.tiptop.constant.Cmd;
import ink.tiptop.common.domain.rsp.PageResponse;
import ink.tiptop.common.domain.rsp.Response;
import ink.tiptop.service.RestartService;
import ink.tiptop.service.ZjfBaseServerInfoService;
import ink.tiptop.utils.ssh.SshUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ink.tiptop.utils.JSON;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ink.tiptop.zjf
 * @Title: boot-server-eureka
 * @Package ink.tiptop.service.impl
 * @Description:
 * @date 2020-08-02 22:48
 */
@Service("restartService")
@Slf4j
public class RestartServiceImpl implements RestartService {

    private static final String RESTART_SERVICE_CACHE_KEY_HEAD = "RESTART_CACHE_KEY_";
    private static final String CLEAR_RESTART_SERVICE_CACHE_KEY_HEAD = "RESTART_CACHE_KEY_*";
    private static final String GET_LIST_RESTART_SERVICE_CACHE_KEY_HEAD = "RESTART_CACHE_KEY_*";

    @Autowired
    private ICache<RestartServiceBean> cache;
    @Autowired
    private ZjfBaseServerInfoService baseServerInfoService;

    /**
     * 把需要重启的服务进行缓存
     *
     * @param service
     * @param server
     */
    @Override
    public RestartServiceBean saveRestartServiceListToCache(ZjfServiceRemoteViewEntity service, ZjfBaseServerInfoEntity server) {
        RestartServiceBean restartServiceBean = getServiceBean(service, server);
        boolean b = cache.setVal(RESTART_SERVICE_CACHE_KEY_HEAD + service.getId(), restartServiceBean, ECaches.DAY);
        log.info("保存重启对象{}到缓存{}", JSON.toJSONString(restartServiceBean), b ? "成功" : "失败");
        return restartServiceBean;
    }

    @Override
    public void clearRestartList() {
        cache.del(CLEAR_RESTART_SERVICE_CACHE_KEY_HEAD);
    }

    @Override
    public Response list(RestartServiceListRequest request) {
        List<RestartServiceBean> list = cache.getList(GET_LIST_RESTART_SERVICE_CACHE_KEY_HEAD, ECaches.DAY);
        return new PageResponse<>(list).total(list.size()).offset(0);
    }

    /**
     * @param request 这里的id是远程视图的ID,
     *                需要从缓存中获取对应的视图配置信息
     * @return
     */
    @Override
    public Response restart(RestartServiceRequest request) {
        List<Integer> reqIdList = request.getId().parallelStream().map(it -> Integer.parseInt(it)).collect(Collectors.toList());
        RestartServiceBean serviceBean = null;
        for (Integer remoteViewId : reqIdList) {
            serviceBean = cache.getVal(RESTART_SERVICE_CACHE_KEY_HEAD + remoteViewId, ECaches.DAY);
            boolean success = restartService(serviceBean);
            if (success) {
                // 重启成功之后 把缓存状态更新掉
                serviceBean.setRestartSuccess(true);
//                cache.setVal(RESTART_SERVICE_CACHE_KEY_HEAD + remoteViewId, serviceBean,ECaches.DAY);
                cache.del(RESTART_SERVICE_CACHE_KEY_HEAD + remoteViewId, ECaches.DAY);
            }
        }
        return WebworkResponse.SUCCEED;
    }

    private boolean restartService(RestartServiceBean serviceBean) {
        // 1.获取配置
        ZjfBaseServerInfoEntity baseServerInfoEntity = getBaseServerInfoEntity(serviceBean);
        // 2.连接
        Connection conn = null;
        try {
            conn = baseServerInfoService.getConnection(baseServerInfoEntity);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            return false;
        }
        // 3.执行
        String restartCmd = String.format(Cmd.RE_START, serviceBean.getServiceParent() + "/" + serviceBean.getServiceName() + serviceBean.getBinStart());
        List<String> exec = null;
        try {
            exec = SshUtil.exec(conn, restartCmd);
            logExec(exec);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }
        // 4.返回
        return true;
    }

    private void logExec(List<String> exec) {
        log.debug("重启返回:");
        for (String info : exec) {
            log.debug(info);
        }
    }

    private ZjfBaseServerInfoEntity getBaseServerInfoEntity(RestartServiceBean serviceBean) {
        ZjfBaseServerInfoEntity entity = new ZjfBaseServerInfoEntity();
        entity.setHost(serviceBean.getServerHost());
        entity.setPort(serviceBean.getServerPort());
        entity.setUser(serviceBean.getServerUser());
        entity.setPass(serviceBean.getServerPass());
        return entity;
    }

    /**
     * 获取丢缓存的 重启服务bean
     *
     * @param service
     * @param server
     * @return
     */
    private RestartServiceBean getServiceBean(ZjfServiceRemoteViewEntity service, ZjfBaseServerInfoEntity server) {
        RestartServiceBean restartServiceBean = new RestartServiceBean();
        restartServiceBean.setServiceId(service.getId());
        restartServiceBean.setServiceParent(service.getParent());
        restartServiceBean.setServiceName(service.getName());
        restartServiceBean.setBinStart(service.getBinStart());
        restartServiceBean.setBinStop(service.getBinStop());
        restartServiceBean.setServiceOrder(service.getOrder());
        restartServiceBean.setServiceDesc(service.getDesc());
        restartServiceBean.setServiceIgnore(service.getIgnore());

        restartServiceBean.setServerId(server.getId());
        restartServiceBean.setServerName(server.getName());
        restartServiceBean.setServerHost(server.getHost());
        restartServiceBean.setServerPort(server.getPort());
        restartServiceBean.setServerUser(server.getUser());
        restartServiceBean.setServerPass(server.getPass());
        restartServiceBean.setServerKey(server.getKey());
        restartServiceBean.setServerDesc(server.getDesc());
        restartServiceBean.setConnWay(server.getConnWay());
        restartServiceBean.setOperator(server.getOperator());
        return restartServiceBean;
    }

}
